package com.mebs.model.inventory;

import com.mebs.model.Company;
import com.mebs.model.Project;
import com.mebs.model.Address;
import com.mebs.model.AuditInfo;
import com.mebs.model.logistics.LogisticsOperation;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;

import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;
import org.jt.jet.annotation.Field;
import org.jt.jet.annotation.ArgumentType;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Feb 13, 2006, 4:57:45 PM
 */
@Entity
@Table(name = "A_ORDER")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractOrder {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id")
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "CompanyId")
    private Company company;

    @ManyToOne(optional = true)
    @JoinColumn(name = "ProjectId")
    private Project project;

    @ManyToOne(optional = true)
    @JoinColumn(name = "DestinationAddressId")
    private Address destination; // vendor destination, not logictics chain?

    @Column(name = "DateOfOrder", nullable = false)
    private Date dateOfOrder;

    @ManyToOne(optional = true)
    @JoinColumn(name = "StatusId")
    private OrderStatus status;

    @Column(name = "Notes", nullable = true, length = 1024)
    private String notes;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "LOGISTICS_ORDER",
        joinColumns = {@JoinColumn(name = "OrderId")},
        inverseJoinColumns = {@JoinColumn(name = "LogisticsOperationId")})
    @Field(type = ArgumentType.INSTANCE)
    private Set<LogisticsOperation> logisticsOperations;

    @Embedded
    private AuditInfo auditInfo;

    @Transient
    public abstract String getSequenceNumber();

    protected AbstractOrder()
    {
    }

    /**
     * ********************** Getters-setters ***********************
     */
    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public Project getProject()
    {
        return project;
    }

    public void setProject(Project project)
    {
        this.project = project;
    }

    public Company getCompany()
    {
        return company;
    }

    public void setCompany(Company company)
    {
        this.company = company;
    }

    public Address getDestination()
    {
        return destination;
    }

    public void setDestination(Address destination)
    {
        this.destination = destination;
    }

    public Date getDateOfOrder()
    {
        return dateOfOrder;
    }

    public void setDateOfOrder(Date dateOfOrder)
    {
        this.dateOfOrder = dateOfOrder;
    }

    public OrderStatus getStatus()
    {
        return status;
    }

    public void setStatus(OrderStatus status)
    {
        this.status = status;
    }

    public String getNotes()
    {
        return notes;
    }

    public void setNotes(String notes)
    {
        this.notes = notes;
    }

    public Set<LogisticsOperation> getLogisticsOperations()
    {
        return logisticsOperations;
    }

    public void setLogisticsOperations(Set<LogisticsOperation> logisticsOperations)
    {
        this.logisticsOperations = logisticsOperations;
    }

    public AuditInfo getAuditInfo()
    {
        if (this.auditInfo == null) {
            this.auditInfo = new AuditInfo();
        }
        return auditInfo;
    }

    public void setAuditInfo(AuditInfo auditInfo)
    {
        this.auditInfo = auditInfo;
    }

    @Override
    public int hashCode()
    {
        if (id == null) return super.hashCode();
        return id.hashCode();
    }

    @Override
    public boolean equals(Object o)
    {
        if (o == null) return false;
        if (this == o) return true;
        if (id == null) return false;
        if (getClassWithoutInitializingProxy(o) != getClassWithoutInitializingProxy(this) &&
            ! getClassWithoutInitializingProxy(o).isAssignableFrom(AbstractOrder.class))
            return false;
        final AbstractOrder that = (AbstractOrder) o;
        return id.equals(that.getId());
    }

}
